package mushystuff.dtb.core.service.pojo;

import mushystuff.dtb.core.dao.ProductDAO;
import mushystuff.dtb.core.dao.SprintDAO;
import mushystuff.dtb.core.dao.TaskDAO;
import mushystuff.dtb.core.dao.UserStoryDAO;
import mushystuff.dtb.core.model.Sprint;
import mushystuff.dtb.core.model.Task;
import mushystuff.dtb.core.model.UserStory;
import mushystuff.dtb.core.service.SprintService;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public final class SprintServiceImpl implements SprintService {

    private Log log = LogFactory.getLog(this.getClass());

    private ProductDAO productDAO;

    private UserStoryDAO userStoryDAO;

    private SprintDAO sprintDAO;
    
    private TaskDAO taskDAO;

    @Required
    public void setProductDAO(ProductDAO productDAO) {
        this.productDAO = productDAO;
    }

    @Required
    public void setUserStoryDAO(UserStoryDAO userStoryDAO) {
        this.userStoryDAO = userStoryDAO;
    }

    @Required
    public void setSprintDAO(SprintDAO sprintDAO) {
        this.sprintDAO = sprintDAO;
    }
    
    @Required
    public void setTaskDAO(TaskDAO taskDAO) {
        this.taskDAO = taskDAO;
    }

    @Override
    public Sprint getSprint(long sprintId) {
        return sprintDAO.getSprint(sprintId);
    }

    @Override
    public void assignUserStoryToSprint(long userStoryId, long sprintId) {
        UserStory userStory = userStoryDAO.getUserStory(userStoryId);
        Sprint sprint = sprintDAO.getSprint(sprintId);
        if (userStory.getProduct() == sprint.getProduct()) {
            boolean added = sprint.getBacklog().add(userStory);
            if (added) {
                userStory.setAssignedSprint(sprint);
                productDAO.persistProduct(sprint.getProduct());
            } else {
                log.warn("User Story " + userStory
                        + " could not be added to sprint " + sprint);
                throw new RuntimeException(
                        "User Story could not be added to sprint");
            }
        } else {
            log.warn("User Story " + userStory + " and sprint " + sprint
                    + " not is same product");
            throw new RuntimeException(
                    "Sprint and user story not in the same product");
        }
    }

    @Override
    public void unassignUserStoryFromSprint(long userStoryId) {
        UserStory userStory = userStoryDAO.getUserStory(userStoryId);
        userStory.setAssignedSprint(null);
        productDAO.persistProduct(userStory.getProduct());
    }

    @Override
    public void assignTaskToUserStory(long taskId, long userStoryId) {
        Task task = taskDAO.getTask(taskId);
        UserStory userStory = userStoryDAO.getUserStory(userStoryId);
        task.setAssignedUserStory(userStory);
        productDAO.persistProduct(task.getSprint().getProduct());
    }

    @Override
    public void unassignTaskFromUserStory(long taskId) {
        Task task = taskDAO.getTask(taskId);
        task.setAssignedUserStory(null);
        productDAO.persistProduct(task.getSprint().getProduct());
    }

}
